"""
爬虫任务状态管理服务 - 连接数据库的真实实现
"""
from typing import Dict, Any, Optional, List
from datetime import datetime
from axiom_boot.di import service, autowired
from axiom_boot.logging.setup import get_logger
from axiom_boot.core.id_generator import IdGenerator
from axiom_boot.database.base_service import BaseService
from axiom_boot.database import transactional

from ..mapper.scraper_task_record_mapper import ScraperTaskRecordMapper
from ..models.scraper_task_record import ScraperTaskRecord

logger = get_logger(__name__)


@service()
class ScraperTaskService(BaseService[ScraperTaskRecord, ScraperTaskRecordMapper]):
    """爬虫任务状态管理服务 - 数据库版本"""
    
    def __init__(self, 
                 mapper: ScraperTaskRecordMapper = autowired(),
                 id_generator: IdGenerator = autowired()):
        super().__init__(mapper)
        self.id_generator = id_generator
    
    @transactional
    async def create_task_record(self, 
                               task_name: str,
                               task_type: str,
                               target_site: str,
                               target_count: int = 0,
                               concurrent_limit: int = 1,
                               config_params: Dict[str, Any] = None) -> str:
        """
        创建爬虫任务记录
        
        Returns:
            task_id: 任务ID
        """
        task_id = await self.id_generator.generate_id()
        
        task_record = ScraperTaskRecord()
        task_record.task_id = str(task_id)
        task_record.task_name = task_name
        task_record.task_type = task_type
        task_record.target_site = target_site
        task_record.target_count = target_count
        task_record.concurrent_limit = concurrent_limit
        task_record.task_status = "pending"
        task_record.config_params = config_params or {}
        
        await self.save(task_record)
        logger.info(f"创建爬虫任务: {task_id} - {task_name}")
        return str(task_id)
    
    @transactional
    async def start_task(self, task_id: str) -> bool:
        """开始执行任务"""
        task_record = await self.find_one_by_filters(task_id=task_id)
        if not task_record:
            return False
            
        task_record.task_status = "running"
        task_record.start_time = datetime.now()
        await self.save(task_record)
        
        logger.info(f"开始执行任务: {task_id}")
        return True
    
    @transactional
    async def update_task_progress(self, 
                                 task_id: str,
                                 total_processed: int = 0,
                                 success_count: int = 0,
                                 failed_count: int = 0) -> bool:
        """更新任务进度"""
        task_record = await self.find_one_by_filters(task_id=task_id)
        if not task_record:
            return False
            
        success_rate = (success_count / max(total_processed, 1)) * 100 if total_processed > 0 else 0
        
        task_record.total_processed = total_processed
        task_record.success_count = success_count
        task_record.failed_count = failed_count
        task_record.success_rate = round(success_rate, 2)
        
        await self.save(task_record)
        logger.info(f"更新任务进度 {task_id}: 总计{total_processed}, 成功{success_count}, 失败{failed_count}")
        return True
    
    @transactional
    async def complete_task(self, 
                          task_id: str,
                          final_stats: Dict[str, Any],
                          error_summary: Optional[str] = None) -> bool:
        """完成任务"""
        task_record = await self.find_one_by_filters(task_id=task_id)
        if not task_record:
            return False
            
        end_time = datetime.now()
        duration = None
        if task_record.start_time:
            duration = int((end_time - task_record.start_time).total_seconds())
        
        task_record.task_status = "completed" if not error_summary else "failed"
        task_record.end_time = end_time
        task_record.duration_seconds = duration
        task_record.total_processed = final_stats.get("total_processed", 0)
        task_record.success_count = final_stats.get("success_count", 0)
        task_record.failed_count = final_stats.get("failed_count", 0)
        task_record.success_rate = final_stats.get("success_rate", 0)
        task_record.error_summary = error_summary
        task_record.failed_items = final_stats.get("failed_items", [])
        
        await self.save(task_record)
        
        status = "completed" if not error_summary else "failed"
        logger.info(f"任务{status}: {task_id}")
        return True
    
    async def get_task_status(self, task_id: str) -> Optional[Dict[str, Any]]:
        """获取任务状态"""
        task_record = await self.find_one_by_filters(task_id=task_id)
        if not task_record:
            return None
        
        return {
            "task_id": task_record.task_id,
            "task_name": task_record.task_name,
            "task_status": task_record.task_status,
            "start_time": task_record.start_time,
            "end_time": task_record.end_time,
            "total_processed": task_record.total_processed,
            "success_count": task_record.success_count,
            "failed_count": task_record.failed_count,
            "success_rate": task_record.success_rate,
            "error_summary": task_record.error_summary
        }
    
    async def cleanup_stale_tasks(self) -> int:
        """清理过期的pending任务"""
        from datetime import datetime, timedelta
        
        # 清理超过1小时仍为pending状态的任务
        cutoff_time = datetime.now() - timedelta(hours=1)
        
        stale_tasks = await self.find_by_filters(
            task_status="pending",
            created_before=cutoff_time
        )
        
        count = 0
        for task in stale_tasks:
            task.task_status = "cancelled"
            task.error_summary = "任务超时自动取消"
            await self.save(task)
            count += 1
            
        logger.info(f"已清理 {count} 个过期的pending任务")
        return count
    
    async def list_recent_tasks(self, limit: int = 10) -> List[Dict[str, Any]]:
        """获取最近的任务列表"""
        from axiom_boot.api.models import PaginationParams
        pagination = PaginationParams(page=1, page_size=limit)
        paginated_result = await self.page(
            pagination=pagination,
            order_by=["create_time DESC"]
        )
        tasks = paginated_result.items
        
        return [
            {
                "task_id": task.task_id,
                "task_name": task.task_name,
                "task_type": task.task_type,
                "task_status": task.task_status,
                "target_site": task.target_site,
                "target_count": task.target_count,
                "total_processed": task.total_processed,
                "success_count": task.success_count,
                "failed_count": task.failed_count,
                "success_rate": task.success_rate,
                "start_time": task.start_time,
                "end_time": task.end_time,
                "create_time": task.create_time
            }
            for task in tasks
        ]
